#region License

// This file is part of Grawlix.
// 
// Grawlix is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as
// published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
// Grawlix is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public
// License along with Grawlix.  If not, see
// <http://www.gnu.org/licenses/>.

#endregion

using System;
using C5;

namespace Grawlix.Services.Resources
{
	/// <summary>
	/// An entry within the 
	/// <see cref="ResourceRepository{TDeclare,TDefine}"/>.
	/// </summary>
	internal class ResourceEntry
	{
		/// <summary>
		/// The list of <see cref="AppDomain"/> objects which have a
		/// copy of the data.
		/// </summary>
		private readonly
			HashSet<AppDomain> _appDomains =
				new HashSet<AppDomain>();

		/// <summary>
		/// Whether the data is currently being loaded.
		/// </summary>
		private bool _isLoading;

		/// <summary>
		/// Whether or not the load has failed.
		/// </summary>
		private bool _loadFailed;

		/// <summary>
		/// The loaded state data, or null.
		/// </summary>
		private object _state;

		/// <summary>
		/// Gets the list of all the 
		/// <see cref="AppDomain"/> objects.
		/// </summary>
		/// <value>The read-only list of caches.</value>
		public ICollection<AppDomain> AppDomainList
		{
			get { return new GuardedCollection<AppDomain>(_appDomains); }
		}

		/// <summary>
		/// Gets a value indicating whether this entry is empty.
		/// </summary>
		/// <value><c>true</c> if this entry is empty; otherwise, 
		/// <c>false</c>.</value>
		public bool IsEmpty
		{
			get { return _appDomains.IsEmpty; }
		}

		/// <summary>
		/// Gets or sets a value indicating whether this instance is
		/// loading.
		/// </summary>
		/// <value>
		/// 	<c>true</c> if this instance is loading; otherwise, 
		/// 	<c>false</c>.
		/// </value>
		public bool IsLoading
		{
			get { return _isLoading; }
			set { _isLoading = value; }
		}

		/// <summary>
		/// Gets or sets a value indicating whether the load failed.
		/// </summary>
		/// <value><c>true</c> if the load failed; otherwise, 
		/// <c>false</c>.</value>
		public bool LoadFailed
		{
			get { return _loadFailed; }
			set { _loadFailed = value; }
		}

		/// <summary>
		/// Gets or sets the state object for this resource.
		/// </summary>
		/// <value>The untyped state object.</value>
		public object State
		{
			get { return _state; }
			set { _state = value; }
		}

		/// <summary>
		/// Adds an <see cref="AppDomain"/> to the list using this
		/// entry.
		/// </summary>
		/// <param name="appDomain">The <see cref="AppDomain"/> to add.
		/// </param>
		/// <exception cref="ArgumentNullException"><c>appDomain</c> is
		/// null.</exception>
		public void AddEnvironment(AppDomain appDomain)
		{
			if (appDomain == null)
				throw new ArgumentNullException("appDomain");
			_appDomains.Add(appDomain);
		}

		/// <summary>
		/// Removes a reference to the specified 
		/// <see cref="AppDomain"/>.
		/// </summary>
		/// <param name="appDomain">The <see cref="AppDomain"/> to
		/// remove.</param>
		/// <exception cref="ArgumentNullException"><c>appDomain</c> is
		/// null.</exception>
		public void RemoveEnvironment(AppDomain appDomain)
		{
			if (appDomain == null)
				throw new ArgumentNullException("appDomain");
			_appDomains.Remove(appDomain);
		}
	}
}